<template>
  <div>
    <n-grid :x-gap="2">
      <n-grid-item :span="7">
        <n-card :style="{ height: `${clientHeight - (layoutHeaderHeight  + tabsHeight + 10 )}px` }">
          <n-form size="small" label-placement="top" :model="text2ImgPrompt" :rules="rules" ref="formRef">
            <n-form-item label="图片尺寸"  path="ar">
              <n-radio-group v-model:value="text2ImgPrompt.ar" size="large">
                <n-radio-button
                    v-for="size in options.sizeOption"
                    :key="size.value"
                    :value="size.value"
                    :label="size.label"
                />
              </n-radio-group>
            </n-form-item>

            <n-form-item label="机器人选择" path="model">
              <n-radio-group v-model:value="text2ImgPrompt.botType" size="large">
                <n-radio-button
                    v-for="model in options.botTypeOption"
                    :key="model.value"
                    :value="model.value"
                    :label="model.label"
                />
              </n-radio-group>
            </n-form-item>

            <n-form-item label="模型选择" path="model">
              <n-radio-group v-model:value="text2ImgPrompt.model" size="large">
                <n-radio-button
                    v-for="model in options.mjModelOption"
                    :key="model.value"
                    :value="model.value"
                    :label="model.label"
                />
              </n-radio-group>
            </n-form-item>
            <n-form-item label="模型选择" :show-label="false">
              <n-radio-group v-model:value="text2ImgPrompt.model" name="size" size="large">
                <n-radio-button
                    v-for="size in options.nijiModelOption"
                    :key="size.value"
                    :value="size.value"
                    :label="size.label"
                />
              </n-radio-group>
            </n-form-item>
          </n-form>
          <n-form label-placement="left" label-width="80" label-align="left">
            <n-form-item label="品质" path="quality">
              <n-select
                  :options="qualityOption"
                  v-model:value="text2ImgPrompt.quality">
              </n-select>
            </n-form-item>

            <n-form-item label="混乱">
              <n-slider v-model:value="text2ImgPrompt.chaos" :step="1" :min="0" :max="100" />
            </n-form-item>

            <n-form-item label="出图模式">
              <n-select
                  v-model:value="text2ImgPrompt.plotMode"
                  :options="options.plotMode">
              </n-select>
            </n-form-item>

            <n-form-item label="其余参数">
              <n-input v-model:value="text2ImgPrompt.command">
              </n-input>
            </n-form-item>

            <n-form-item label="允许垫图" v-if="props.mode==='config'">
              <n-radio-group v-model:value="text2ImgPrompt.enableReferencePic">
                <n-radio :value="true">是</n-radio>
                <n-radio :value="false">否</n-radio>
              </n-radio-group>
            </n-form-item>
          </n-form>

          <n-form-item label="参考图" :show-label="false" v-if="props.mode==='image'">
            <n-card title="参考图片" bordered>
              <template #header-extra>
                <n-button size="small" type="warning" style="margin-left: 5px;" @click="resetImg">清除</n-button>
              </template>
              <n-space justify="center">
                <div class="canvas-wrapper">
                  <n-image
                      ref="img2img_imgRef"
                      :style="{
                        width: canvasWidth + 'px',
                        height: canvasHeight + 'px'
                      }"
                      v-if="text2ImgPrompt.base64"
                      :src="text2ImgPrompt.base64"
                      alt=""
                      @load="handleImgLoad"/>
                </div>
                <n-empty description="未上传图片" v-if="!text2ImgPrompt.base64">
                  <template #extra>
                    <n-upload
                        :custom-request="customRequest"
                    >
                      <n-button>上传图片</n-button>
                    </n-upload>
                  </template>
                </n-empty>
              </n-space>
            </n-card>
          </n-form-item>
        </n-card>
      </n-grid-item>
      <n-grid-item :span="17">
        <n-card :style="{ height: `${clientHeight - (layoutHeaderHeight  + tabsHeight + 10)}px` }">
          <n-form  >
            <n-form-item label="图片提示词" v-if="props.mode==='image'">
              <n-input
                v-model:value="text2ImgPrompt.prompt"
                type="textarea"
                style="height: 60px">
              </n-input>
            </n-form-item>

            <n-form-item label="预设提示词" v-if="props.mode==='config'">
              <n-input
                  v-model:value="text2ImgPrompt.prompt"
                  type="textarea"
                  style="height: 60px">
              </n-input>
            </n-form-item>

            <n-form-item label="不想出现的元素">
              <n-input
                  v-model:value="text2ImgPrompt.no"
                  type="textarea"
                  style="height:60px">
              </n-input>
            </n-form-item>



            <n-space justify="space-between">
              <n-button type="info" @click="promptDrawerShow=true" style="margin-right: 5px;">提示词</n-button>
              <n-button
                  type="primary"
                  @click="formSubmit"
                  style="width: 100px"
                  :loading="sumbitLoading"
                  v-if="props.mode ==='image' "
              >
                提交绘画
              </n-button>
            </n-space>
          </n-form>
          <n-divider title-placement="left" style="margin-bottom: 5px;margin-top: 10px;" v-if="props.mode==='image'"> 绘画记录 </n-divider>
          <n-scrollbar :style="{ height: `${clientHeight - (layoutHeaderHeight  + tabsHeight + 345 )}px` }" v-if="props.mode==='image'">
            <n-grid :x-gap="5" :y-gap="5" :cols="4" v-if="props.mode==='image'">
              <n-grid-item v-for="mjTask in history">
                <n-card footer-style="padding:5px 5px 5px 5px;height:70px;" content-style="padding: 5px 5px 5px 5px">
                  <template #cover>
                    <div class="image-container-lora">
                      <n-image :src="mjTask.imageUrl" object-fit="scale-down" lazy></n-image>
                    </div>
                  </template>
                  <n-row v-if="mjTask.status === 'IN_PROGRESS'" style="margin-bottom: 5px;">
                    <n-tag> 进度: {{mjTask.progress}}</n-tag>
                  </n-row>
                  <n-row>
                    <n-space>
                      <n-tag v-if="mjTask.status==='SUCCESS'" type="success"> 成功</n-tag>
                      <n-tag v-else-if="mjTask.status==='IN_PROGRESS'" type="success"> 出图中</n-tag>
                      <n-tag v-else-if="mjTask.status==='NOT_START'" type="success"> 未开始</n-tag>
                      <n-tag v-else type="error">
                        失败
                      </n-tag>
                      <n-tag type="info">{{dayjs(mjTask.submitTime).format('YYYY-MM-DD HH:mm')}}</n-tag>
                    </n-space>
                  </n-row>
                  <n-row style="margin-top: 5px;padding-left: 5px;padding-right: 5px;">
                    <n-ellipsis>
                      提示词: {{mjTask.promptEn}}
                    </n-ellipsis>
                  </n-row>

                  <template #footer>
                    <n-row>
                      <n-space justify="start" style="width: 100%" v-if="mjTask.status==='SUCCESS'">
                        <n-button-group name="upscale" v-if=" (mjTask.action === 'MJ_IMAGINE' || mjTask.action==='MJ_VARIATION') && mjTask.status === 'SUCCESS'">
                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(1,task.id)"
                          >
                            <template #trigger>
                              <n-button size="small">U1</n-button>
                            </template>
                            <span>确定放大左上角照片吗?</span>
                          </n-popconfirm>

                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(2,task.id)"
                          >
                            <template #trigger>
                              <n-button  size="small">U2</n-button>
                            </template>
                            <span>确定放大右上角照片吗?</span>
                          </n-popconfirm>

                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(3,task.id)"
                          >
                            <template #trigger>
                              <n-button  size="small">U3</n-button>
                            </template>
                            <span>确定放大左下角照片吗?</span>
                          </n-popconfirm>

                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(4,task.id)"
                          >
                            <template #trigger>
                              <n-button  size="small">U4</n-button>
                            </template>
                            <span>确定放大右下角照片吗?</span>
                          </n-popconfirm>
                        </n-button-group>

                        <n-popconfirm
                            :show-icon="false"
                            :negative-text="null"
                            @positive-click="handleUpscale(4,task.id)"
                        >
                          <template #trigger>
                            <n-button  size="small">U4</n-button>
                          </template>
                          <span>确定放大右下角照片吗?</span>
                        </n-popconfirm>
                      </n-space>

                      <n-space v-if="mjTask.status === 'FAILURE'">
                        {{mjTask.failReason}}
                      </n-space>
                    </n-row>
                    <n-row>
                      <n-space justify="start" style="width: 100%">
                        <n-button-group name="upscale" v-if=" (mjTask.action === 'MJ_IMAGINE' || mjTask.action==='MJ_VARIATION') && mjTask.status === 'SUCCESS'">
                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(1,task.id)"
                          >
                            <template #trigger>
                              <n-button size="small">U1</n-button>
                            </template>
                            <span>确定放大左上角照片吗?</span>
                          </n-popconfirm>

                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(2,task.id)"
                          >
                            <template #trigger>
                              <n-button  size="small">U2</n-button>
                            </template>
                            <span>确定放大右上角照片吗?</span>
                          </n-popconfirm>

                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(3,task.id)"
                          >
                            <template #trigger>
                              <n-button  size="small">U3</n-button>
                            </template>
                            <span>确定放大左下角照片吗?</span>
                          </n-popconfirm>

                          <n-popconfirm
                              :show-icon="false"
                              :negative-text="null"
                              @positive-click="handleUpscale(4,task.id)"
                          >
                            <template #trigger>
                              <n-button  size="small">U4</n-button>
                            </template>
                            <span>确定放大右下角照片吗?</span>
                          </n-popconfirm>
                        </n-button-group>
                      </n-space>
                    </n-row>
                  </template>
                </n-card>
              </n-grid-item>

            </n-grid>
          </n-scrollbar>

        </n-card>
      </n-grid-item>
    </n-grid>

    <n-drawer v-model:show="promptDrawerShow" :width="drawerWidth">
      <n-drawer-content title="提示词选择器" closable>
        <promptTemplate code="02" @loadPrompt-event="loadPromptEvent"></promptTemplate>
      </n-drawer-content>
    </n-drawer>

  </div>
</template>
<script lang="ts" setup>


import {onMounted, reactive, ref} from "vue";
import {UploadCustomRequestOptions} from 'naive-ui';
import PromptTemplate from "@/components/prompt/promptTemplate.vue";
import {mjControllerApi} from "@/api/mj/mjController.api";
import dayjs from "dayjs";
import {storeToRefs} from "pinia";
import {useSystemStore} from "@/store/modules/useSystemStore";
import useIntervalAsync from "@/components/common/useIntervalAsync";
const {
  clientHeight,
  layoutHeaderHeight,
  darkTheme,
  tabsHeight
} = storeToRefs(useSystemStore());

const history = ref([])
// 设置canvas宽高
const canvasWidth = ref(200)
const canvasHeight = ref(200)
const drawerWidth = ref(600)
const sumbitLoading = ref(false)
const options = {
  sizeOption: [{
    label: '1:1',
    value: '1:1'
  }, {
    label: '4:3',
    value: '4:3'
  }, {
    label: '16:9',
    value: '16:9'
  },{
    label: '3:4',
    value: '3:4'
  },{
    label: '9:16',
    value: '9:16'
  }],

  mjModelOption: [ {
    label: 'MJ v6.0',
    value: 'MJv6'
  },{
    label: 'MJ v5.1',
    value: 'MJv5.1'
  },{
    label: 'MJ v5.2',
    value: 'MJv5.2'
  },{
    label: 'MJ v5.0',
    value: 'MJv5'
  }],
  nijiModelOption: [
    {
      label: 'NJ v6.0',
      value: 'NIJIv6'
    },{
      label: 'NJ v5.0',
      value: 'NIJIv5'
    },{
      label: 'NJ v4.0',
      value: 'NIJIv4'
    }
  ],
  qualityOption: [
    {
      label: '高清',
    }
  ],
  plotMode: [
    {
      label: '慢速',
      value: '1'
    },{
      label: '快速',
      value: '2'
    },{
      label: '涡轮',
      value: '3'
    }
  ],
  botTypeOption: [ {
    label: 'MJ机器人',
    value: 'mjbot'
  },{
    label: 'NIJI机器人',
    value: 'nijibot'
  }],
}

const qualityOption = [
  {
    label: '高',
    value: 'high'
  },{
    label: '中',
    value: 'hormal'
  },{
    label: '低',
    value: 'low'
  }
]

const promptDrawerShow = ref(false)
const formRef = ref(null)

const text2ImgPrompt = ref(reactive({
  ar: '1:1',
  model: 'MJv6',
  quality: 'high',
  chaos: 0,
  mode: '普通',
  base64: '',
  prompt: '',
  no:'',
  plotMode: '2',
  command: '',
  resourceId:'',
  enableReferencePic: false,
  botType:'mjbot'
}))

const props = defineProps({
  mode: {
    type: String,
    default: 'image'
  }
})



const handleImgLoad = (e: any) => {
  const image = e.target;
  let image_new = new Image()
  image_new.src = image.src
  image_new.onload = function () {
    // storyPaintConfig.value.defaultWidth = image_new.width
    // storyPaintConfig.value.defaultHeight = image_new.height
    // 计算图片宽高比例
    let imgRatio = image_new.width / image_new.height
    if (image_new.width > 200
        || image_new.height > 200) {
      // 计算缩放后的宽高
      if (imgRatio > 1) {
        canvasWidth.value = 200
        canvasHeight.value = image_new.height / (image_new.width / 200)
      } else {
        // 图片比较宽
        canvasWidth.value = image_new.width / (image_new.height / 200)
        canvasHeight.value = 200
      }
    } else {
      canvasWidth.value = image_new.width
      canvasHeight.value = image_new.height
    }
  }
}

const customRequest = (uploadOption: UploadCustomRequestOptions) => {
  const reader = new FileReader();
  //@ts-ignore
  reader.readAsDataURL(uploadOption.file.file);
  reader.onloadend = () => {
    let image = new Image()
    image.src = reader.result as any
    //@ts-ignore
    text2ImgPrompt.value.base64 = reader.result
  };
}

const resetImg = () => {
  text2ImgPrompt.value.base64 = ''
}

const loadPromptEvent = (prompt:string,negativePrompt:string) => {
  text2ImgPrompt.value.prompt = prompt;
  promptDrawerShow.value = false;
}



/**初始化事件**/
onMounted(() => {
  // 设置当前drawerWidth 宽度
  drawerWidth.value = window.innerWidth - 300;
  window.addEventListener('resize', function (){
    drawerWidth.value = window.innerWidth - 300;
  });
})


const time = ref(0)
/**提交任务**/
const formSubmit =  async () => {
  sumbitLoading.value = true
  time.value = 0
  mjControllerApi.imagine(text2ImgPrompt.value).then(res => {
    if(res.code === 200 ){
      window.$message.success('提交成功,请等待出图')
      history.value.unshift({
        status: 'NOT_START',
        startTime: new Date(),
        promptEn: text2ImgPrompt.prompt
      })
      recover()
    }
    sumbitLoading.value = false
  }).finally(() => {
    sumbitLoading.value = false
  })
}



const { flush, cancel, recover } = useIntervalAsync(async () => {
  time.value += 1
  mjControllerApi.history().then(res => {
    if(res.code === 200){
      history.value = res.data
      const index = history.value.findIndex((item:any) => {
        if(  (item.status === 'IN_PROGRESS' || item.status==='NOT_START') && (new Date().getTime() - new Date(item.submitTime).getTime() < 20 * 60 * 1000) ){
          return true
        }
      })
      console.log(index)
      if(index == -1 && time.value > 5) {
        cancel()
      }
    }
  })
}, 1000 * 5);




const rules = {
  ar: {
    required: true,
    message: '请选择尺寸信息'
  },
  model: {
    required: true,
    message: '请选择模型'
  }
};

const loadConfig = (paintConfig: string, selectedResource: string) => {
  if (paintConfig != null && paintConfig.length > 0) {
    const config = JSON.parse(paintConfig)
    text2ImgPrompt.value.resourceId = config.resourceId
    text2ImgPrompt.value.ar = config.ar
    text2ImgPrompt.value.model = config.model
    text2ImgPrompt.value.quality = config.quality
    text2ImgPrompt.value.chaos = config.chaos
    text2ImgPrompt.value.plotMode = config.plotMode
    text2ImgPrompt.value.command = config.command
    text2ImgPrompt.value.enableReferencePic = config.enableReferencePic
    text2ImgPrompt.value.prompt = config.prompt
    text2ImgPrompt.value.no = config.no
  }
}



const getConfig = async () => {
  return Promise.all([
    validateForm(formRef)
  ]).then(async (results) => {
    const allValid = results.every((valid) => valid)
    console.log(allValid)
    if (allValid) {
      return {...text2ImgPrompt.value}
    }else {
      return null
    }
  })
}



const validateForm = (fr:any) =>{
  return new Promise((resolve) => {
    fr.value?.validate((errors) => {
      console.log(errors)
      if(!errors){
        resolve(true)
      }else {
        resolve(false)
      }
    });
  });
}

defineExpose({
  getConfig, loadConfig
})

</script>

<style scoped>
.image-container-lora {
  height: 250px; /* 设置容器的固定高度 */
  display: flex; /* 使用Flex布局 */
  align-items: center; /* 垂直居中 */
  justify-content: center; /* 水平居中 */
}
</style>
